package cn.ddiancan.schedule.task.service;

import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

import cn.ddiancan.schedule.base.domain.TaskDTO;
import cn.ddiancan.schedule.base.service.ITaskTimerService;
import cn.ddiancan.schedule.task.CronTaskRegistrar;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.config.CronTask;

/**
 * job调度服务类
 *
 * @author Amos
 */
@RequiredArgsConstructor
public class SchedulerService implements DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(SchedulerService.class);

    private final ITaskTimerService taskTimerService;

    private final DistributedLockService distributedLockService;

    private final ApplicationContext applicationContext;

    private final CronTaskRegistrar cronTaskRegistrar;

    public static ConcurrentHashMap<String, CronTask> extutorMap = new ConcurrentHashMap<>();

    /**
     * 刷新任务清单
     */
    public void refreshTaskTimer() {
        logger.info("refreshTaskTimer begin load executor map.....");
        List<TaskDTO> allEnableTaskTimer = taskTimerService.getAllEnableTaskTimer();
        logger.info("allEnableTaskTimer size:{}.....", allEnableTaskTimer.size());
        allEnableTaskTimer.stream().forEach(task -> {
            try {
                CronTask async = getAsync(task);
                // 主要做任务清洗
                if (!extutorMap.containsKey(task.getScheduleCode())) {
                    extutorMap.put(task.getScheduleCode(), async);
                    cronTaskRegistrar.addCronTask(async);
                }
                logger.info("已加载定时任务 task:{}.....", async.getExpression());

            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        });
        logger.info("refreshTaskTimer  loaded executor map.....task keys:{}",
            extutorMap.keySet().stream().collect(Collectors.joining(",")));
    }

    public CronTask getAsync(TaskDTO taskDTO) {
        return new CronTask(new SchedulingRunnable(taskDTO, applicationContext,distributedLockService), taskDTO.getCron());
    }

    @Override
    public void destroy() throws Exception {
        logger.info("destroy...");
        logger.info("清理redis中锁信息-----------");
        distributedLockService.releaseAllLock(extutorMap.keySet().stream().collect(Collectors.toList()));
        logger.info("清理缓存map信息-----------");
        extutorMap.clear();
    }
}
